#include <iostream>
#include <dirent.h> // 文件系统相关库
#include "LinkTree.h"
#include <sys/stat.h> // 系统库

std::string Double2(double num)
{
    return std::to_string((1.0 *(int)(num * 100)) / 100);
}

std::string Transform(size_t size)
{
    if(size < 1024)
        return std::to_string(size) + "B";
    else if(size < 1024 * 1024)  
        return Double2((1.0 * size) / 1024) + "KB";
    else if(size < 1024 * 1024 * 1024)
        return Double2((1.0 * size) / (1024 * 1024)) + "MB";
    else
        return Double2((1.0 * size) / (1024 * 1024 * 1024)) + "GB";
}

// 扫描文件夹
void ExploreDirectory(const std::string &path, TreeNode *node)
{
    // 打开文件夹
    // c_str()是C++字符串和C语言的常量字符串之间转换的桥梁接口（很重要）
    DIR *dir = opendir((path + "/").c_str());
    // 打开失败
    if(dir == nullptr)
    {
        std::cout<<"文件夹路径有误！："<<path<<std::endl;
        return;
    }
    // 读取文件目录下的文件列表
    dirent *e = nullptr;
    while((e = readdir(dir)) != nullptr)
    {
        if(std::string(e->d_name) == "." || std::string(e->d_name) == "..")
            continue;
        TreeNode *child = new TreeNode(e->d_name);
        child->Connect(node);
        // 不是所有文件都能递归，得是文件夹才能递归
        if(e->d_type == DT_DIR) // 目录文件
        {
            ExploreDirectory(path + "/" + std::string(e->d_name), child);
        }
        else
        {
            struct stat s;
            stat((path + "/" + std::string(e->d_name)).c_str(), &s);
            child->SetData(std::string(e->d_name) + "   size:" + Transform(s.st_size));
        }
    }
    // 关闭目录流（所有东西打开都要关闭）
    closedir(dir);
}

void Find(LinkTree &tree, const std::string &name)
{
    DARRAY::DynamicArray a = tree.FindByElement(name);
    for(int i = 0; i < a.Size(); i++)
    {
        std::cout<<tree.GetNodePath((TreeNode *)a[i])<<std::endl;
    }
}

// main函数也可以有参数
// argc代表命令行参数数量
// argv代表命令行参数值数组
int main(int argc, char *argv[])
{
    std::string path;
    if(argc < 2)
        path = ".";
    else
        path = argv[1]; 
    LinkTree tree(path);
    ExploreDirectory(path, tree.GetRoot());

    struct stat s;
    stat("./a.out", &s);
    std::cout<<"文件大小："<<s.st_size<<std::endl;

    tree.show();

    // if(argc >= 3)
    // {
    //     Find(tree, argv[2]);
    // }
    // else
    // {
    //     std::cout<<"未输入查找的文件名！\n";
    // }

    // DARRAY::DynamicArray a = tree.FindByElement("a.out");

    // for(int i = 0; i < a.Size(); i++)
    // {
    //     std::cout<<tree.GetNodePath((TreeNode *)a[i])<<std::endl;
    // }
    
    return 0;
}